home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / bipl.zip / PROGS.ZIP / PARSE.ICN < prev    next >
Text File  |  1992-09-28  |  3KB  |  124 lines

  1. ###########################################################################
  2. #
  3. #    File:     parse.icn
  4. #
  5. #    Subject:  Program to parse simple statements
  6. #
  7. #    Author:   Kenneth Walker
  8. #
  9. #    Date:     December 22, 1989
  10. #
  11. ############################################################################
  12.  
  13. global lex    # co-expression for lexical analyzer
  14. global next_tok    # next token from input
  15.  
  16. record token(type, string)
  17.  
  18. procedure main()
  19.    lex := create ((!&input ? get_tok()) | |token("eof", "eof"))
  20.    prog()
  21. end
  22.  
  23. #
  24. # get_tok is the main body of lexical analyzer
  25. #
  26. procedure get_tok()
  27.    local tok
  28.    repeat {    # skip white space and comments
  29.       tab(many('     '))
  30.       if ="#" | pos(0) then fail
  31.  
  32.       if any(&letters) then    # determine token type
  33.          tok := token("id", tab(many(&letters ++ '_')))
  34.       else if any(&digits) then
  35.          tok := token("integer", tab(many(&digits)))
  36.       else case move(1) of {
  37.          ";"    :    tok := token("semi", ";")
  38.          "("    :    tok := token("lparen", "(")
  39.          ")"    :    tok := token("rparen", ")")
  40.          ":"    :    if ="=" then tok := token("assign", ":=")
  41.                        else tok := token("colon", ":")
  42.          "+"    :    tok := token("add_op", "+")
  43.          "-"    :    tok := token("add_op", "-")
  44.          "*"    :    tok := token("mult_op", "*")
  45.          "/"    :    tok := token("mult_op", "/")
  46.          default    :    err("invalid character in input")
  47.          }
  48.       suspend tok
  49.       }
  50. end
  51.  
  52. #
  53. # The procedures that follow make up the parser
  54. #
  55.  
  56. procedure prog()
  57.    next_tok := @lex
  58.    stmt()
  59.    while next_tok.type == "semi" do {
  60.       next_tok := @lex
  61.       stmt()
  62.       }
  63.    if next_tok.type ~== "eof" then
  64.       err("eof expected")
  65. end
  66.  
  67. procedure stmt()
  68.    if next_tok.type ~== "id" then
  69.       err("id expected")
  70.    write(next_tok.string)
  71.    if (@lex).type ~== "assign" then
  72.       err(":= expected")
  73.    next_tok := @lex
  74.    expr()
  75.    write(":=")
  76. end
  77.  
  78. procedure expr()
  79.    local op
  80.  
  81.    term()
  82.    while next_tok.type == "add_op" do {
  83.       op := next_tok.string
  84.       next_tok := @lex
  85.       term()
  86.       write(op)
  87.       }
  88. end
  89.  
  90. procedure term()
  91.    local op
  92.  
  93.    factor()
  94.    while next_tok.type == "mult_op" do {
  95.       op := next_tok.string
  96.       next_tok := @lex
  97.       factor()
  98.       write(op)
  99.       }
  100. end
  101.  
  102. procedure factor()
  103.    case next_tok.type of {
  104.       "id" | "integer": {
  105.          write(next_tok.string)
  106.          next_tok := @lex
  107.          }
  108.       "lparen": {
  109.          next_tok := @lex
  110.          expr()
  111.          if next_tok.type ~== "rparen" then
  112.             err(") expected")
  113.          else
  114.             next_tok := @lex
  115.          }
  116.       default:
  117.          err("id or integer expected")
  118.       }
  119. end
  120.  
  121. procedure err(s)
  122.    stop(" ** error **  ", s)
  123. end
  124.